【Chef Solo】attributeはどう使い分けるべきか。
こんにちは、せーのです。 Chef SoloやKnife SoloにChef Server同様environmentがサポートされてから、レシピの書き方が一気に広がりました。 広がった結果、Attributeをどこに書いていいのか迷う人も多いのではないでしょうか。私は迷います。 Chefは結構ゆるーい感じなので、特に「こういう場合にはここに書きなさい」という決まりがあまりありません。 この「決まりがない」というのがクセモノで、ついついAttributeをバラバラに書いてしまい、Cookbookが会社の共有資産になった時に余計な値が埋め込まれる、という事例が多発したりしないでしょうか。私はします。
Attributeには順位があり、より上位の場所にAttributeを書くと下位の値が上書きされます。まずこの順番を体感で覚えておくことが重要です。 Attributeの順位はドキュメントに書いてあります。
英語ですね。ややこしいですね。ざっくり解説します。
Attributeが書けるファイル
Attributeが書けるファイルはAttributeファイル、recipeファイル、Environmentファイル、Roleファイルの4つとchef client起動時にOhaiが自動設定するAutomatic Attributeです。 上書きされる順番は弱い順にAttribute→recipe→Environment→Roleになります。 ただし、これが一部入れ替わったりします。ですが、感覚的にはこれで覚えてしまって問題ないかと思います。 そしてAutomatic Attributeは親玉です。ジョーカーです。最強です。誰も勝てません。
Attributeの強さ
Attributeの強さは弱い順にdefault→force_default→normal→override→force_override→automaticと分かれています。 これと上のファイルを組み合わせる、というのが基本です。 つまりAttributeファイルに書いたdefaultのattributeはEnvironmentファイルに同名のdefault attributeを書いた場合上書きされ、それはさらにrecipeファイルに書いたforce_defaultのattributeで上書きされる、、、といった具合です。
そうなると5種類のファイル × 6種類の強さで30パターンあるように見えますが、attributeのパターンは全部で15種類になります。つまり、組み合わせによって書けないパターンもあるのです。
組み合わせ方と上書き順
それを踏まえたattributeの組み合わせ方と上書きの順番はこのようになります。
四角で囲った部分が間違いやすいポイントです。roleやenvironmentにはforce_default attributeは書けないということ、override attributeの上書き順が何故か変わっていることに注意してください。
では、軽く実践してみましょう。
軽く検証
今回は簡単にApacheを入れてWebルートに当たる/var/www/html/index.htmlを作ります。そのbody部分を上書きしてみます。 サーバーはVirtualBoxでもVMWareでも何でも良いのですが、AWSコンサルティングらしくEC2を使ってみたいと思います。
まずcookbookを作ります。今回は[attrtest]という名前にします(chef soloとknife soloを使います。予めインストールしてください)。
knife solo init chef-repo cd chef-repo/ knife cookbook create attrtest -o site-cookbooks
次にrecipeです。
#yumのfastestmirrorとアップデートをする。 yum_package "yum-fastestmirror" do action :install end execute "yum-update" do user "root" command "yum -y update" action :run end #apacheを入れる package "httpd" do action :install end #apacheの起動 service "httpd" do action [:start, :enable] end #ルートindex.htmlの記述 template "/var/www/html/index.html" do source "index.html.erb" mode 0644 variables( :message=>node['attrfrom']['message'] ) end
この['attrfrom']['message']にattributeの変数を埋めていきます。
次に表示部分であるindex.htmlのテンプレート、index.html.erbを書いていきます。
<!DOCTYPE html> <html> <head> <title>Attribute overrides test</title> </head> <body> This Attribute message from <%= @message %>. </body> </html>
最下位であるAttributeファイルにdefaultでattributeを書いてみます。
default['attrfrom']['message']="attribute file"
それではサーバーにchefを入れてレシピを流してみましょう。 EC2の場合はssh接続とほぼ変わらない形でknifeコマンドが流せます。
knife solo prepare [email protected] -i [EC2のkey pair(パーミッションを600にする)] knife solo cook [email protected] -i [EC2のkey pair(パーミッションを600にする)]
すると最後の方にテンプレートの結果が出ますのでそれで確認できます。
* template[/var/www/html/index.html] action create - create new file /var/www/html/index.html - update content in file /var/www/html/index.html from none to 0fd886 --- /var/www/html/index.html 2014-06-05 06:42:36.733322208 +0000 +++ /tmp/chef-rendered-template20140605-21177-y1k9x9 2014-06-05 06:42:36.745322116 +0000 @@ -1 +1,11 @@ + + + + + + + + This Attribute message from attribute file. + + - change mode from '' to '0644'
ちなみに同じattributeを同じ場所に書くと、下に書いた方で上書きされます。 site-cookbooks/attrtest/attributes/default.rb
default['attrfrom']['message']="attribute file" default['attrfrom']['message']="attribute file below"
* template[/var/www/html/index.html] action create - update content in file /var/www/html/index.html from 0fd886 to 629c4c --- /var/www/html/index.html 2014-06-05 06:42:36.745322116 +0000 +++ /tmp/chef-rendered-template20140605-25243-ibn15w 2014-06-05 07:00:03.130583375 +0000 @@ -5,7 +5,7 @@ - This Attribute message from attribute file. + This Attribute message from attribute file below.
次にこれをenvironmentで上書きしてみます。 /environments/attr.json
{ "name": "attr", "description": "attribute overrides test", "chef_type": "environment", "json_class": "Chef::Environment", "default_attributes": { "attrfrom": { "message":"environment file" } } }
* template[/var/www/html/index.html] action create - update content in file /var/www/html/index.html from 0fd886 to d93bbd --- /var/www/html/index.html 2014-06-05 07:07:48.069424054 +0000 +++ /tmp/chef-rendered-template20140605-27484-3kd2py 2014-06-05 07:12:04.317591645 +0000 @@ -5,7 +5,7 @@ - This Attribute message from attribute file. + This Attribute message from environment file.
まとめ
こんな感じで上書きされることを理解すれば、あとはどこに何を書くか、をルール化してしまうのが楽です。 ちなみに私は
Attributeファイル=>文言変更 recipeファイル=>テスト的に変えたいものがある時のみ。本番では消す。 Environmentファイル=>development(開発),alpha(実験用)、staging(テスト)、production(本番)でのIPやOSバージョンの違い。同じ構成が複数台ある時もここで区別。 Role=>ミドルウェアのバージョン違い
でdefaultとoverrideのみ使います。
参考にしてみてください。